//封装一格函数，求任意数的最小值，并且把最小值当成函数的返回值
function min() {
    var min = arguments[0];
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i] < min) {
            min = arguments[i];
        }
    }
    return min;
}

// 格式化时间对象的函数
function formatDate(d) {
    var year = d.getFullYear();
    var month = d.getMonth() + 1;
    month = month < 10 ? "0" + month : month;

    var date = d.getDate();
    date = date < 10 ? "0" + date : date;

    var hour = d.getHours();
    hour = hour < 10 ? "0" + hour : hour;

    var min = d.getMinutes();
    min = min < 10 ? "0" + min : min;

    var sec = d.getSeconds();
    sec = sec < 10 ? "0" + sec : sec;

    var day = d.getDay();

    var arr = [
        "星期天",
        "星期一",
        "星期二",
        "星期三",
        "星期四",
        "星期五",
        "星期六",
    ];
    return {
        year: year,
        month: month,
        date: date,
        hour: hour,
        min: min,
        sec: sec,
        week: day,
    };
}

// 封装函数（求两个时间对象的差数）
/* 
    参数：两个时间对象
    返回值：以对象形式把相差的天数 小时 分钟和秒数返回 
*/
function timeDifference(date1, date2) {
    var time1 = date1.getTime();
    var time2 = date2.getTime();

    var t = Math.abs(time1 - time2);
    var day = parseInt(t / 1000 / 60 / 60 / 24);
    var h = parseInt(t / 1000 / 60 / 60) % 24;
    var m = parseInt(t / 1000 / 60) % 60;

    var s = parseInt(t / 1000) % 60;
    // console.log(`两个时间相差${day}天${h}小时${m}分钟${s}秒`);
    return {
        d: day,
        h: h,
        m: m,
        s: s,
    };
}

// 封装一个获取样式的函数
/* 
    参数：
        ele:获取样式的元素
        attr:获取什么样式
    返回值：
        获取的样式
*/
function getStyle(ele, attr) {
    var style;
    if (window.getComputedStyle) {
        style = window.getComputedStyle(ele)[attr];
    } else {
        style = ele.currentStyle[attr];
    }

    return style;
}

// 封装一个给元素设置样式的函数
/* 
    参数：
        ele:给哪个元素设置样式
        attr:设置样式的属性
        value:设置样式的属性的属性值
*/

// 封装一个事件监听的函数
/* 
    参数：
        ele：事件源
        type：事件类型
        cb：事件处理函数
    返回值：
        不需要返回值
*/
function addEvent(ele, type, cb) {
    if (ele.addEventListener) {
        ele.addEventListener(type, cb);
    } else {
        ele.attachEvent("on" + type, cb);
    }
}

// 封装一个设置样式的函数
function setStyle(ele, option) {
    //遍历对象
    for (var key in option) {
        ele.style[key] = option[key];
    }
}

// 封装的动画函数
/* 
    参数：
        ele：dom          参与动画的元素（必须）
        option:object     参与动画的属性 和目标是 （必须）
        callback:function 动画执行完成之后需要执行代码（选填）
*/
function move(ele, option, callback) {
    let len = 0; // 用于记录动画的个数（参与动画的属性个数）
    for (let key in option) {
        len++;
        clearInterval(ele[key]);
        ele[key] = setInterval(() => {
            let style = parseInt(getStyle(ele, key));

            let speed = (option[key] - style) / 10;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            style += speed;

            ele.style[key] = style + "px";
            if (style == option[key]) {
                clearInterval(ele[key]);
                len--;
                if (len != 0) return;
                callback && callback();
            }
        }, 30);
    }
}




 // 设置cookie
            /* 
                cookie 属性 必填
                cookie 属性值 必填
                cookie的过期时间 以分钟为单位 选填

                当把过期时间设置为负数的时候 表示删除cookie
                当cookie中已经存在这个属性，那么就是修改
            */
 function setCookie(key, value, expires) {
            if (!key || !value) {
                throw Error("key和value不能为空");
            }
            if (!expires) {
                document.cookie = `${key}=${value};path=/`;
            }
            let date = new Date();
            time = date - 8 * 60 * 60 * 1000 + expires * 60 * 1000;
            date.setTime(time);

            document.cookie = `${key}=${value};path=/;expires=${date}`
}
        



        //获取cookie的属性值
function getCookie(key) {
            // 获取所有的cookie
            let cookie = document.cookie;
            // name=123; age=30 ==> {name:'123',age:30}
            let arr = cookie.split("; "); //['name=123', 'age=30']以分号加空格分割
            let obj = {};
            arr.forEach((item) => {
                let res = item.split("=");
                obj[res[0]] = res[1];
            });

            // 判断是否有传递参数，
            // 如果没有传递 那么就直接返回对象
            // 如果有传递就返回这个传递属性的属性值
            if (!key) return obj;

            return obj[key];
}

            //     参数：
            //         请求的路径
            //         请求方式
            //         是否异步
            //         请求的参数
            //         请求成功的回调函数
            //         请求失败的回调函数

            //         因为这些参数有些是可选的，当可选参数不填写的时候 会导致实参给形参赋值的时候乱序
            //         把所有的参数当对象中的属性传递
            //             {
            //                 url:'接口', 必填
            //                 type:'get|post', 选填，默认值为get
            //                 async:true|false, 选填，默认值为true
            //                 data:'name=aa&age=18' | {name:'aa',age:18} || 没有  ，选填，，默认值:''
            //                 success:function(){}, 必填
            //                 error:fucntion(){}    选填 默认值：function(){}
            //             }
            // */
            
            function ajax(option) {
                // 【1】判断option的数据类型，如果不是对象，手动抛出错误
                if (
                    Object.prototype.toString.call(option) != "[object Object]"
                ) {
                    throw Error("ajax函数的参数必须是一个对象");
                }

                // 【2】判断必填的属性是否存在 url success
                if (!(option.url && option.success)) {
                    throw Error("url 和success 属性是必填的");
                }

                // 【3】success属性的属性值必须是一个函数
                if (
                    Object.prototype.toString.call(option.success) !=
                    "[object Function]"
                ) {
                    throw Error("success属性的属性值必须是一个函数");
                }

                // 【4】async的值是否是布尔值
                if ( option.async && Object.prototype.toString.call(option.async) != "[object Boolean]"
                ) {
                    throw Error("async 的取值必须是布尔值");
                }

                // 【5】给选填的属性添加默认值
                let param = {
                    url: option.url,
                    type: option.type || "get",
                    async: option.async == false ? option.async : true,
                    data:option.data || '',
                    success:option.success,
                    error:option.error || function(){}
                };

                // 【6】判断type属性属性值是否为get 和post
                if (!(param.type == "get" || param.type == "post")) {
                    throw Error("type属性的取值暂时只支持get 和post");
                }

                // 【7】data 属性的判断
                // data 数据类型只能为字符串 或者 对象
                if(!(Object.prototype.toString.call(param.data) == '[object String]'|| Object.prototype.toString.call(param.data) == '[object Object]') ){
                    throw Error('data属性的值 只支持字符串或者 对象');
                }

                // 【8】如果data属性的值为对象 需要把对象转换为字符串
                if(Object.prototype.toString.call(param.data) == '[object Object]'){
                   let str = '';
                   for(let key in param.data){
                       str += key +'=' + param.data[key] + '&';
                   }
                   param.data = str.substr(0,str.length-1);

                }

                // 发送ajax请求
                let xhr = new XMLHttpRequest();
                if(param.type == 'get'){
                    xhr.open(param.type, param.url + '?' + param.data,param.async);
                    xhr.send();
                }else{
                    xhr.open(param.type,param.url,param.async);
                    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
                    xhr.send(param.data);
                }

                if(param.async == false){
                    param.success(xhr.responseText);
                }

                // 事件驱动程序
                xhr.onload = function () {
                    param.success(xhr.responseText);
                };
            }